import {
  registerValidateRules,
  registerValidateFormats,
  registerValidateLocale,
} from '@formily/core';

import template from 'es6-template-strings';

import { groupBy } from 'lodash';
import { xhr_get } from '@/biz-components/_common/request';

registerValidateFormats({});

registerValidateLocale({
  'zh-CN': {
    json_serialize: 'JSON 序列化失败请输入正确的json对象',
    check_multilingual: '语种重复',
    check_repeat: ' ${value} 重复',
    checkPrcsCode: '编码已存在',
    checkRepaidAmt: '本次还款金额必须大于零小于借款未清金额',
    check_error_file_upload: '文件上传失败',
    check_file_upload: '文件上传中',
    check_field_repeat: '类型 ${type}: ${field} 重复',
  },
});

registerValidateLocale({
  'en-US': {
    json_serialize: 'JSON Serialization failed. Please enter the correct JSON object',
    check_multilingual: 'Language repetition',
    check_repeat: '${value} repetition',
    checkPrcsCode: 'Code is exist',
    checkRepaidAmt: 'Repaid amount must more than zero and less then remain loan amount',
    check_error_file_upload: 'File upload failed',
    check_file_upload: 'File uploading',
    check_field_repeat: 'type  ${type}: ${field} field repeat',
  },
});

registerValidateRules({
  json_serialize: (value: any, rule: any, b: any) => {
    let serialize = true;

    try {
      if (value) {
        const json = JSON.parse(value);
        serialize = Object.prototype.toString.call(json) === '[object Object]';
      }
    } catch (err) {
      serialize = false;
    }

    return serialize ? '' : rule.message || '';
  },
  check_multilingual: (value: any, rule: any) => {
    if (Array.isArray(value)) {
      const lngType = groupBy(value, 'lngType');

      const repeatLngType = Object.keys(lngType).filter(
        (key) => key !== 'undefined' && lngType[key].length > 1,
      );

      return repeatLngType.length ? rule.message : '';
    }

    return '';
  },
  check_repeat: (value: any, rule: any) => {
    if (Array.isArray(value)) {
      const lngType = groupBy(value, rule.check_repeat);

      const repeatLngType = Object.keys(lngType).filter(
        (key) => key !== 'undefined' && lngType[key].length > 1,
      );

      return repeatLngType.length
        ? template(rule.message, {
            value: repeatLngType.join(','),
          })
        : '';
    }

    return '';
  },

  check_field_repeat: (value: any, rule: any) => {
    if (Array.isArray(value)) {
      const typeGroup = groupBy(value, 'type') || {};

      let type = '';

      let field: any[] = [];

      Object.keys(typeGroup).forEach((key) => {
        const columnType = groupBy(typeGroup[key], 'key');
        const fieldType = Object.keys(columnType).filter((key) => columnType[key].length > 1);
        if (fieldType.length) {
          type = key;
          field = fieldType;
        }
      });

      return type
        ? template(rule.message, {
            type,
            field: field.join(','),
          })
        : '';
    }
    return '';
  },

  checkPrcsCode: (prcsCode: any, rule: any): Promise<string> => {
    if (prcsCode) {
      return xhr_get('/bpm/prcsDef/checkPrcsCode', { prcsCode })
        .then((res: any) => {
          return res.success && res.result ? Promise.resolve('') : Promise.resolve(rule.message);
        })
        .catch((err) => {
          return Promise.resolve(rule.message);
        });
    }
    return Promise.resolve('');
  },
});
